package cn.com.aiouyi.util;

import cn.com.aiouyi.common.ExceptionCode;
import cn.com.aiouyi.entity.BusinessExceptionLog;
import cn.com.aiouyi.entity.SystemExceptionLog;
import cn.com.aiouyi.service.BusinessExceptionLogService;
import cn.com.aiouyi.service.SystemExceptionLogService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * Created by tommy on 2018/4/10.
 */
@Slf4j
@Component
public class LogHelper {

    @Resource(name = "businessExceptionLogServiceImpl")
    private BusinessExceptionLogService businessExceptionLogService;

    @Resource(name = "systemExceptionLogServiceImpl")
    private SystemExceptionLogService systemExceptionLogService;

    private static LogHelper logHelper;

    @PostConstruct
    public void init() {
        logHelper = this;
        logHelper.businessExceptionLogService = this.businessExceptionLogService;
        logHelper.systemExceptionLogService = this.systemExceptionLogService;
    }

    public enum Type {
        DEBUG,

        INFO,

        WARN,

        ERROR
    }

    /**
     * @param type 日志类型
     * @param exceptionCode 异常代码
     * @param e 异常信息
     * @param description 自定义描述
     * @param diyParams 自定义参数
     * @param isBusinessException 是否是业务异常，如果不是则是系统异常
     * @param isSavedToDatabase 是否记录到数据库
     * */
    public static String logger(Type type, ExceptionCode exceptionCode, Exception e, String description,
                                Map<String, Object> diyParams, boolean isBusinessException, boolean isSavedToDatabase){
        String exceptionMessage = e.getMessage();
        String exceptionStackTrace = ExceptionHelper.getExceptionStackTrace(e);
        return logger(type, exceptionCode, exceptionMessage, exceptionStackTrace, description, diyParams,
                isBusinessException, isSavedToDatabase);
    }

    /**
     * @param type 日志类型
     * @param exceptionCode 异常代码
     * @param t 异常信息
     * @param description 自定义描述
     * @param diyParams 自定义参数
     * @param isBusinessException 是否是业务异常，如果不是则是系统异常
     * @param isSavedToDatabase 是否记录到数据库
     * */
    public static String logger(Type type, ExceptionCode exceptionCode, Throwable t, String description,
                                Map<String, Object> diyParams, boolean isBusinessException, boolean isSavedToDatabase){
        String exceptionMessage = t.getMessage();
        String exceptionStackTrace = ExceptionHelper.getThrowableStackTrace(t);
        return logger(type, exceptionCode, exceptionMessage, exceptionStackTrace, description, diyParams,
                isBusinessException, isSavedToDatabase);
    }

    /**
     * @param type 日志类型
     * @param exceptionCode 异常代码
     * @param exceptionMessage 异常信息
     * @param description 自定义描述
     * @param diyParams 自定义参数
     * @param isBusinessException 是否是业务异常，如果不是则是系统异常
     * @param isSavedToDatabase 是否记录到数据库
     * */
    @Transactional
    private static String logger(Type type, ExceptionCode exceptionCode, String exceptionMessage, String exceptionStackTrace,
                                 String description, Map<String, Object> diyParams, boolean isBusinessException, boolean isSavedToDatabase){
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        StringBuilder reqParams = new StringBuilder("");
        StringBuilder reqMethod = new StringBuilder("");
        StringBuilder reqUrl = new StringBuilder("");
        StringBuilder reqIP = new StringBuilder("");
        if (requestAttributes == null){

        } else {
            HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();

            Map paramMap = request.getParameterMap();

            //获取req中参数
            reqParams.append(JSON.toJSONString(CommUtil.mapToJsonObject(paramMap)));

            //获取req method
            reqMethod.append(request.getMethod());

            //获取req uri
            reqUrl.append(request.getRequestURL().toString());

            //获取req ip
            reqIP.append(CommUtil.getIpAddr(request));
        }


        //获取传过来的参数
        String diyParam = diyParams == null ? "" : new JSONObject(diyParams).toString();

        StringBuilder sb = new StringBuilder();
        //"Exception=<{错误类型}-{错误代码}-{错误信息}>|__|Diy=<{自定义描述}-{方法参数}>|__|User=<{类型}-{ID}>|__|RequestParams=<{请求参数}-{请求方法}>|__|RequestUrl=<{请求路径}>|__|IP=<{IP}>"
//        String logMsg = "Exception=<{}-{}-{}>|__|Diy=<{}-{}>|__|User=<{}-{}>|__|RequestParams=<{}-{}>|__|RequestUrl=<{}>|__|IP=<{}>";

        String userType = "admin";
        Long userId = 1L;
        sb.append("Exception=<").append(type.toString()).append("-").append(exceptionCode).append("-").append(exceptionMessage).append(">")
                .append("|__|").append("Diy=<").append(description).append("-").append(diyParam).append(">")
                .append("|__|").append("User=<").append(userType).append("-").append(userId).append(">")
                .append("|__|").append("RequestParams=<").append(reqParams).append("-").append(reqMethod).append(">")
                .append("|__|").append("RequestUrl=<").append(reqUrl).append(">")
                .append("|__|").append("IP=<").append(reqIP).append(">");

        //是否需要存入数据库
        if (isSavedToDatabase){
            //是业务异常
            if (isBusinessException){
                BusinessExceptionLog t = new BusinessExceptionLog();
                t.setExceptionCode(exceptionCode.toString());
                t.setExceptionMessage(exceptionMessage==null?"":exceptionMessage);
                t.setExceptionStackTrace(exceptionStackTrace);
                t.setDescription(description);
                t.setDiyParams(diyParam);
                t.setUserType(userType);
                t.setUserId(userId);
                t.setReqParams(reqParams.toString());
                t.setReqMethod(reqMethod.toString());
                t.setReqUrl(reqUrl.toString());
                t.setReqIp(reqIP.toString());
                logHelper.businessExceptionLogService.save(t);
            }
            //是系统异常
            else {
                SystemExceptionLog t = new SystemExceptionLog();
                t.setExceptionCode(exceptionCode.toString());
                t.setExceptionMessage(exceptionMessage==null?"":exceptionMessage);
                t.setExceptionStackTrace(exceptionStackTrace);
                t.setDescription(description);
                t.setDiyParams(diyParam);
                t.setUserType(userType);
                t.setUserId(userId);
                t.setReqParams(reqParams.toString());
                t.setReqMethod(reqMethod.toString());
                t.setReqUrl(reqUrl.toString());
                t.setReqIp(reqIP.toString());
                logHelper.systemExceptionLogService.save(t);
            }
        }

        return sb.toString();
    }

}
